package com.jzlin.funhub.admin.service.file;

import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzlin.funhub.admin.mapper.FileStorageMapper;
import com.jzlin.funhub.admin.model.dto.FileUploadResultDTO;
import com.jzlin.funhub.admin.model.entity.FileStorage;
import com.jzlin.funhub.admin.model.resp.FileUploadResp;
import com.jzlin.funhub.admin.service.file.strategy.IFileStorageStrategy;
import com.jzlin.funhub.framework.core.exception.FileStorageException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.LocalDateTime;

/**
 * 文件管理服务.
 *
 * @author linjz
 * @since 2025/8/8
 */
@Service
public class FileManagerService extends ServiceImpl<FileStorageMapper, FileStorage> {

    @Autowired
    private IFileStorageStrategy fileStorageStrategy;

    public FileUploadResp upload(MultipartFile file, String businessType) throws FileStorageException {
        String basePath = buildBasePath(businessType);
        String fileId = IdUtil.fastSimpleUUID();
        // 上传文件
        FileUploadResultDTO uploadResultDTO = fileStorageStrategy.upload(file, basePath + fileId);
        //保持记录表
        FileStorage fileStorage = new FileStorage();
        fileStorage.setFileId(fileId);
        fileStorage.setFileExtension(uploadResultDTO.getFileExtension());
        fileStorage.setOriginalFilename(uploadResultDTO.getOriginalFilename());
        fileStorage.setFileSize(uploadResultDTO.getFileSize());
        fileStorage.setStoragePath(uploadResultDTO.getStoragePath());
        fileStorage.setStrategy(uploadResultDTO.getStrategy());
        this.save(fileStorage);

        FileUploadResp vo = new FileUploadResp();
        vo.setFileId(fileId);
        vo.setFileSize(uploadResultDTO.getFileSize());
        vo.setOriginalFilename(uploadResultDTO.getOriginalFilename());
        return vo;
    }

    public InputStream download(String fileId) throws FileStorageException {
        return fileStorageStrategy.download(getByFileId(fileId).getStoragePath());
    }

    public void delete(Long fileId) throws FileStorageException {
        this.update().eq("fileId", fileId).set("del", true).update();
    }

    /**
     * 基础路径:/{businessType}/{year}/{month}/
     *
     * @param businessType 业务类型
     * @return 文件根路径
     */
    private String buildBasePath(String businessType) {
        LocalDateTime now = LocalDateTime.now();
        return StrFormatter.format("/{}/{}/{}/", businessType, String.valueOf(now.getYear()), String.valueOf(now.getMonthValue()));
    }

    /**
     * 获取文件名称
     * @param fileId 文件id
     * @return
     */
    public String getOriginalFilename(String fileId) {
        return getByFileId(fileId).getOriginalFilename();
    }

    public FileStorage getByFileId(String fileId) {
        FileStorage fileStorage = this.query().eq("file_id", fileId).eq("del", false).one();
        if (fileStorage == null) {
            throw new FileStorageException(StrFormatter.format("文件{}不存在！", fileId));
        }
        return fileStorage;
    }
}
